import { action, useParams, useAction, createAsync, useSubmission, json } from "@solidjs/router" import { createMemo, Match, Show, Switch, createEffect } from "solid-js" import { createStore } from "solid-js/store" import { Billing } from "@opencode-ai/console-core/billing.js" import { withActor } from "~/context/auth.withActor" import { IconAlipay, IconCreditCard, IconStripe, IconUpi, IconWechat } from "~/component/icon" import styles from "./billing-section.module.css" import { createCheckoutUrl, formatBalance, queryBillingInfo } from "../../common" import { useI18n } from "~/context/i18n" import { localizeError } from "~/lib/form-error" const createSessionUrl = action(async (workspaceID: string, returnUrl: string) => { "use server" return json( await withActor( () => Billing.generateSessionUrl({ returnUrl }) .then((data) => ({ error: undefined, data })) .catch((e) => ({ error: e.message as string, data: undefined, })), workspaceID, ), { revalidate: queryBillingInfo.key }, ) }, "sessionUrl") export function BillingSection() { const params = useParams() const i18n = useI18n() // ORIGINAL CODE - COMMENTED OUT FOR TESTING const billingInfo = createAsync(() => queryBillingInfo(params.id!)) const checkoutAction = useAction(createCheckoutUrl) const checkoutSubmission = useSubmission(createCheckoutUrl) const sessionAction = useAction(createSessionUrl) const sessionSubmission = useSubmission(createSessionUrl) const [store, setStore] = createStore({ showAddBalanceForm: false, addBalanceAmount: billingInfo()?.reloadAmount.toString() ?? "", checkoutRedirecting: false, sessionRedirecting: false, }) createEffect(() => { const info = billingInfo() if (info) { setStore("addBalanceAmount", info.reloadAmount.toString()) } }) const balance = createMemo(() => formatBalance(billingInfo()?.balance ?? 0)) async function onClickCheckout() { const amount = parseInt(store.addBalanceAmount) const baseUrl = window.location.href const checkout = await checkoutAction(params.id!, amount, baseUrl, baseUrl) if (checkout && checkout.data) { setStore("checkoutRedirecting", true) window.location.href = checkout.data } } async function onClickSession() { const baseUrl = window.location.href const sessionUrl = await sessionAction(params.id!, baseUrl) if (sessionUrl && sessionUrl.data) { setStore("sessionRedirecting", true) window.location.href = sessionUrl.data } } function showAddBalanceForm() { while (true) { checkoutSubmission.clear() if (!checkoutSubmission.result) break } setStore({ showAddBalanceForm: true, }) } function hideAddBalanceForm() { setStore("showAddBalanceForm", false) checkoutSubmission.clear() } // DUMMY DATA FOR TESTING - UNCOMMENT ONE OF THE SCENARIOS BELOW // Scenario 1: User has not added billing details and has no balance // const balanceInfo = () => ({ // balance: 0, // paymentMethodType: null as string | null, // paymentMethodLast4: null as string | null, // reload: false, // reloadError: null as string | null, // timeReloadError: null as Date | null, // }) // Scenario 2: User has not added billing details but has a balance // const balanceInfo = () => ({ // balance: 1500000000, // $15.00 // paymentMethodType: null as string | null, // paymentMethodLast4: null as string | null, // reload: false, // reloadError: null as string | null, // timeReloadError: null as Date | null // }) // Scenario 3: User has added billing details (reload enabled) // const balanceInfo = () => ({ // balance: 750000000, // $7.50 // paymentMethodType: "card", // paymentMethodLast4: "4242", // reload: true, // reloadError: null as string | null, // timeReloadError: null as Date | null // }) // Scenario 4: User has billing details but reload failed // const balanceInfo = () => ({ // balance: 250000000, // $2.50 // paymentMethodType: "card", // paymentMethodLast4: "4242", // reload: true, // reloadError: "Your card was declined." as string, // timeReloadError: new Date(Date.now() - 3600000) as Date // 1 hour ago // }) // Scenario 5: User has Link payment method // const balanceInfo = () => ({ // balance: 500000000, // $5.00 // paymentMethodType: "link", // paymentMethodLast4: null as string | null, // reload: true, // reloadError: null as string | null, // timeReloadError: null as Date | null // }) return (

{i18n.t("workspace.billing.title")}

{i18n.t("workspace.billing.subtitle.beforeLink")}{" "} {i18n.t("workspace.billing.contactUs")}{" "} {i18n.t("workspace.billing.subtitle.afterLink")}

${balance()} {i18n.t("workspace.billing.currentBalance")}
{ setStore("addBalanceAmount", e.currentTarget.value) checkoutSubmission.clear() }} placeholder={i18n.t("workspace.billing.enterAmount")} />
{(err: any) =>
{localizeError(i18n.t, err())}
}
} >
}>
----}> •••• {billingInfo()?.paymentMethodLast4} {i18n.t("workspace.billing.linkedToStripe")} {i18n.t("workspace.billing.alipay")} {i18n.t("workspace.billing.wechat")}
) }